﻿#include <iostream>
#include <vector>
#include <cmath>
#include <random>
#include <algorithm>

using namespace std;

// AP 参数定义
struct AP {
    double x, y, z;    // AP的坐标
    int channel;       // 使用的信道（1、6、11为非重叠信道）
};

// 墙体信息
enum WallType { CONCRETE, PARTITION, GLASS };
struct Wall {
    double x1, y1, x2, y2;  // 墙的起点与终点
    WallType type;
};

// 教学楼参数
const double LENGTH = 100.0; // 教学楼长度
const double WIDTH = 80.0;   // 教学楼宽度
const double HEIGHT = 3.5;   // 每层高度
const int FLOORS = 3;        // 楼层数

// 墙体衰减
double getWallAttenuation(WallType type) {
    switch (type) {
    case CONCRETE: return 12.0;
    case PARTITION: return 6.0;
    case GLASS: return 7.0;
    default: return 0.0;
    }
}

// 判断两线段是否相交
bool segmentsIntersect(double Ax, double Ay, double Bx, double By,
    double Cx, double Cy, double Dx, double Dy) {
    // 快速排斥试验
    if (max(Ax, Bx) < min(Cx, Dx) || max(Cx, Dx) < min(Ax, Bx) ||
        max(Ay, By) < min(Cy, Dy) || max(Cy, Dy) < min(Ay, By)) {
        return false;
    }

    // 跨立试验
    double cross1 = (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax);
    double cross2 = (Bx - Ax) * (Dy - Ay) - (By - Ay) * (Dx - Ax);
    if (cross1 * cross2 > 0) return false;

    double cross3 = (Dx - Cx) * (Ay - Cy) - (Dy - Cy) * (Ax - Cx);
    double cross4 = (Dx - Cx) * (By - Cy) - (Dy - Cy) * (Bx - Cx);
    if (cross3 * cross4 > 0) return false;

    return true;
}

double calculateSignalStrength(const AP& ap, double x, double y, double z, const vector<Wall>& walls) {
    double dx = ap.x - x;
    double dy = ap.y - y;
    double dz = ap.z - z;
    double distance = sqrt(dx * dx + dy * dy + dz * dz);

    if (distance < 1.0) distance = 1.0; // 防止距离过小导致信号过强

    // 自由空间路径损耗 (FSPL) 计算，假设使用2.4GHz
    double freq = 2400; // MHz
    double signalStrength = -20 * log10(distance) - 20 * log10(freq) - 32.44;

    // 墙体衰减计算
    for (const auto& wall : walls) {
        if (segmentsIntersect(ap.x, ap.y, x, y, wall.x1, wall.y1, wall.x2, wall.y2)) {
            signalStrength -= getWallAttenuation(wall.type);
        }
    }

    return signalStrength;
}

// 生成非重叠信道（1、6、11）
int getNonOverlappingChannel(mt19937& gen) {
    vector<int> channels = { 1, 6, 11 };
    uniform_int_distribution<> dist(0, 2);
    return channels[dist(gen)];
}

vector<AP> optimizeAPPlacement(int numAPs, int floor, const vector<Wall>& walls) {
    vector<AP> bestAPs;
    double bestScore = -INFINITY; // 评分综合考虑覆盖率和信道干扰

    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> distX(0, LENGTH);
    uniform_real_distribution<> distY(0, WIDTH);

    for (int i = 0; i < 500; ++i) { // 尝试500组AP布局
        vector<AP> candidateAPs;
        for (int j = 0; j < numAPs; ++j) {
            AP ap;
            ap.x = distX(gen);
            ap.y = distY(gen);
            ap.z = floor * HEIGHT;
            ap.channel = getNonOverlappingChannel(gen); // 非重叠信道
            candidateAPs.push_back(ap);
        }

        // 计算覆盖率
        int coveredPoints = 0;
        int totalPoints = 0;
        for (double x = 0; x <= LENGTH; x += 2.0) {
            for (double y = 0; y <= WIDTH; y += 2.0) {
                double maxSignal = -1000.0;
                for (const auto& ap : candidateAPs) {
                    double signal = calculateSignalStrength(ap, x, y, floor * HEIGHT, walls);
                    if (signal > maxSignal) maxSignal = signal;
                }
                if (maxSignal >= -65.0) coveredPoints++;
                totalPoints++;
            }
        }
        double coverage = static_cast<double>(coveredPoints) / totalPoints;

        // 计算干扰得分（信道冲突次数）
        int interference = 0;
        for (size_t a = 0; a < candidateAPs.size(); ++a) {
            for (size_t b = a + 1; b < candidateAPs.size(); ++b) {
                double distance = sqrt(pow(candidateAPs[a].x - candidateAPs[b].x, 2) +
                    pow(candidateAPs[a].y - candidateAPs[b].y, 2));
                if (distance < 30.0 && // 30米内视为相邻AP
                    abs(candidateAPs[a].channel - candidateAPs[b].channel) % 5 != 0) {
                    interference++;
                }
            }
        }
        double interferenceScore = exp(-interference / 5.0); // 指数衰减转换

        // 综合评分：覆盖率权重0.8，干扰得分权重0.2
        double score = 0.8 * coverage + 0.2 * interferenceScore;

        if (score > bestScore) {
            bestScore = score;
            bestAPs = candidateAPs;
        }
    }

    return bestAPs;
}

int main() {
    int numAPs = 5; // 每层放置的AP数量

    // 定义墙体：外墙和内部隔断
    vector<Wall> walls = {
        // 外墙
        {0, 0, 100, 0, CONCRETE},
        {0, 0, 0, 80, CONCRETE},
        {0, 80, 100, 80, CONCRETE},
        {100, 0, 100, 80, CONCRETE},
        // 内部横向墙体
        {0, 40, 100, 40, PARTITION},
        // 内部纵向墙体
        {50, 0, 50, 40, PARTITION}
    };

    for (int floor = 0; floor < FLOORS; ++floor) {
        cout << "优化第 " << floor + 1 << " 层的AP位置..." << endl;
        vector<AP> bestAPs = optimizeAPPlacement(numAPs, floor, walls);

        cout << "最佳AP位置与信道分配：" << endl;
        for (const auto& ap : bestAPs) {
            cout << "位置 (" << ap.x << ", " << ap.y << ", " << ap.z
                << "), 信道: " << ap.channel << endl;
        }
        cout << endl;
    }

    return 0;
}